#ifndef MEASUR_E452_ALGBASE_H
#define MEASUR_E452_ALGBASE_H

#include "MeasurE452ParaMeterClass.h"

//const string dir_edge_extraction_parameters("/home/qzs/DataFile/WyData/452MeasureData/edge_extraction_parameters/");
//const string dir_template_classifier_model( "/home/qzs/DataFile/WyData/452MeasureData/template_classifier_model/");
//const string dir_template_feature_model( "/home/qzs/DataFile/WyData/452MeasureData/template_feature_model/");
//const string dir_template_images( "/home/qzs/DataFile/WyData/452MeasureData/template_images/");

class MeasurE452AlgBase
{
public:
    MeasurE452AlgBase()=default;
    MeasurE452AlgBase(int n);
    virtual ~MeasurE452AlgBase();
    static void InitFunAll(const int n);

    /***********************************************************************
     *  @function
     *  @brief
     *  @param
     *  @return
    ***********************************************************************/
    static bool InitPath(const std::string &path);

    /***********************************************************************
      *  @function SetTemplatePath
      *  @brief    设置s_model文件夹的目录
      *  @param    path：s_model文件夹的目录
      *  @return
     ***********************************************************************/
    static bool SetTemplatePath(const std::string &path);

    /***********************************************************************
      *  @function SetStandarVal
      *  @brief    设置标准值
      *  @param
      *  @return
     ***********************************************************************/
    static void SetStandardVal(const std::map<string, float> standardVal);

    /***********************************************************************
     *  @function
     *  @brief
     *  @param
     *  @return
    ***********************************************************************/
    static bool LoadFitPara();

    /***********************************************************************
     *  @function
     *  @brief
     *  @param
     *  @return
    ***********************************************************************/
    static void InitStandardVal(const std::map<string, float> standardVal);

    /***********************************************************************
     *  @function
     *  @brief
     *  @param
     *  @return
    ***********************************************************************/
    float CalcMeasureDistance(const vector<float> &coefficient, float measureItem);

    static std::vector< std::shared_ptr<std::condition_variable>> cvarptrVec;
    static std::vector < std::shared_ptr<std::mutex>  > mtxptrVec;
//    static std::vector< std::shared_ptr<std::condition_variable>> cvarptrfrontVec;
//    static std::vector < std::shared_ptr<std::mutex>  > mtxptrfrontVec;
//    static std::vector< std::shared_ptr<std::condition_variable>> cvarptrsideVec;
//    static std::vector < std::shared_ptr<std::mutex>  > mtxptrsideVec;

//    static std::vector <bool> flagfrontVec;
//    static std::vector <bool> flagsideVec;
    static void setNumberOfAlg(const int n);
    void TemplateMatch(cv::Mat &img, ParameterClassE452 &obj, std::vector<cv::Rect> &rangVec);
    void CoordinateTransformation(std::vector<cv::Point2f> &ptsVec, cv::Point2f &ptsIn,cv::Point2f &ptsOut);
    inline void ImageCoordinateTransformation(std::vector<cv::Point> &ptsInVec,std::vector<cv::Rect> &rangVec)
    {
        for(auto ptr=ptsInVec.begin();ptr!=ptsInVec.end();ptr++)
        {
            ptr->x+=static_cast<int>(rangVec[0].x);
            ptr->y+=static_cast<int>(rangVec[0].y);
        }
    }
    inline void ImageCoordinateTransformation(std::vector<cv::Point2f> &ptsInVec,std::vector<cv::Rect> &rangVec)
    {
        for(auto ptr=ptsInVec.begin();ptr!=ptsInVec.end();ptr++)
        {
            ptr->x+=static_cast<float>(rangVec[0].x);
            ptr->y+=static_cast<float>(rangVec[0].y);
        }
    }
    inline void Pt2ftoPt(std::vector<cv::Point2f> &pt2fVec,std::vector<cv::Point> &ptVec)
    {
        for(auto &elem:pt2fVec)
        {
            cv::Point pt(static_cast<int>(elem.x),static_cast<int>(elem.y));
            ptVec.push_back(pt);
        }
    }
    static void clearAllflag();

public:
    static std::vector <bool> flagVec;

protected:
    static std::vector<std::vector<Point2f>> datumBackVec;
    static std::vector<std::vector<Point2f>> datumFrontVec;
    static std::vector<std::vector<Point2f>> datumSideVec;
    static once_flag m_flag;
    static std::vector<ParameterClassE452> m_dataAllVec;


    static once_flag               m_setStandardValOnceFlag         ;
    static std::string             m_dir_edge_extraction_parameters ;
    static std::string             m_dir_template_classifier_model  ;
    static std::string             m_dir_template_feature_model     ;
    static std::string             m_dir_template_images            ;

public:
    static std::map<string, float> m_standardValMap                 ;
    static string                  m_dir_distance_fitting_model     ;
    static std::map<std::string, std::vector<float>> m_phypixpara[4];
};

#endif // MEASUR_E452_ALGBASE_H
